package wowraidmanager.client.wishlist.user;

import java.util.ArrayList;

import wowraidmanager.client.BaseComposite;
import wowraidmanager.client.service.wishlist.MemberService;
import wowraidmanager.client.service.wishlist.MemberServiceAsync;
import wowraidmanager.client.wishlist.utils.CheckError;
import wowraidmanager.shared.model.wishlist.Member;
import wowraidmanager.shared.model.wishlist.UserStatus;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

public class Userlist extends BaseComposite{

    private static UserlistUiBinder uiBinder = GWT.create(UserlistUiBinder.class);

    protected MemberServiceAsync memberService = GWT.create(MemberService.class);

    private UserStatus userStatus;

    private ArrayList<Member> userListMember;

    private ArrayList<Member> mainUserListMember;

    private ArrayList<Member> subUserListMember;

    static int COLUMN_GUILDNAME = 0;
    static int COLUMN_REALM = 1;
    static int COLUMN_TYPE = 2;
    static int COLUMN_MEMBERNAME = 3;
    static int COLUMN_ORDER = 4;
    static int COLUMN_MEMBERACCOUNT = 5;
    static int COLUMN_DELETEMEMBER = 6;
    static int COLUMN_HIDDENKEY = 7;

    interface UserlistUiBinder extends UiBinder<Widget, Userlist>{
    }

    @UiField
    ListBox userTypeList;

    @UiField
    FlexTable userList;

    @UiField
    Button setButton;

    public Userlist(UserStatus userStatus){
        initWidget(uiBinder.createAndBindUi(this));
        this.userStatus = userStatus;
        setUserList();
        setButton();
        setListBox();
    }

    private void setListBox(){
        userTypeList.addChangeHandler(new ChangeHandler(){

            public void onChange(ChangeEvent event){
                getuserTypelist();
            }
        });
    }

    private void setButton(){
        setButton.addClickHandler(new ClickHandler(){

            public void onClick(ClickEvent event){
                if(userTypeList.getItemText(userTypeList.getSelectedIndex()).equals("MainCharacter")){
                    setMainCharacterListService();
                }else{
                    setSubCharacterListService();
                }

            }
        });

    }

    protected void setSubCharacterListService(){
        boolean isAdmin = userStatus.isAdmin();
        boolean isOfficer = userStatus.isOfficer();
        for(int row = 1;row < userList.getRowCount();row++){
            Hidden keyHidden = (Hidden)userList.getWidget(row, COLUMN_HIDDENKEY);
            String key = keyHidden.getValue();
            for(Member targetMember:subUserListMember){
                if(targetMember.getKey().toString().equals(key)){
                    TextBox guildName = (TextBox)userList.getWidget(row, COLUMN_GUILDNAME);
                    TextBox realmName = (TextBox)userList.getWidget(row, COLUMN_REALM);
                    Label type = (Label)userList.getWidget(row, COLUMN_TYPE);
                    TextBox memberName = (TextBox)userList.getWidget(row, COLUMN_MEMBERNAME);

                    String orderString;
                    String memberAccountString;

                    if(isAdmin || isOfficer){
                        TextBox order = (TextBox)userList.getWidget(row, COLUMN_ORDER);
                        TextBox memberAccount = (TextBox)userList.getWidget(row, COLUMN_MEMBERACCOUNT);
                        orderString = order.getText();
                        memberAccountString = memberAccount.getText();
                    }else{
                        Hidden order = (Hidden)userList.getWidget(row, COLUMN_ORDER);
                        Hidden memberAccount = (Hidden)userList.getWidget(row, COLUMN_MEMBERACCOUNT);
                        orderString = order.getValue();
                        memberAccountString = memberAccount.getValue();
                    }

                    String guildNameString = guildName.getText();
                    String realmNameString = realmName.getText();
                    String memberTypeString = type.getText();
                    String memberNameString = memberName.getText();

                    errorString = CheckError.checkCreateUser(guildNameString, realmNameString, memberNameString, memberAccountString, orderString);

                    if(errorString.equals("")){
                        targetMember.setGuild(guildNameString);
                        targetMember.setRealm(realmNameString);
                        targetMember.setMembertype(memberTypeString);
                        targetMember.setMemberName(memberNameString);
                        targetMember.setOrder(Long.valueOf(orderString));
                        targetMember.setMemberAccount(memberAccountString);
                    }
                    break;
                }
                if(!errorString.equals("")){
                    break;
                }
            }
            if(!errorString.equals("")){
                break;
            }
        }

        if(errorString.equals("")){
            memberService.setMember(subUserListMember, new AsyncCallback<Void>(){

                public void onSuccess(Void result){
                    setInfoMessage("Userの更新に成功しました。");
                    clearErrorMessage();
                }

                public void onFailure(Throwable caught){
                    clearInfoMessage();
                    setErrorMessage("Userの更新に失敗しました。");
                }
            });
        }else{
            clearInfoMessage();
            setErrorMessage(errorString);
        }
    }

    protected void setMainCharacterListService(){
        for(int row = 1;row < userList.getRowCount();row++){
            Hidden keyHidden = (Hidden)userList.getWidget(row, COLUMN_HIDDENKEY);
            String key = keyHidden.getValue();
            for(Member targetMember:mainUserListMember){
                if(targetMember.getKey().toString().equals(key)){
                    TextBox guildName = (TextBox)userList.getWidget(row, COLUMN_GUILDNAME);
                    TextBox realmName = (TextBox)userList.getWidget(row, COLUMN_REALM);
                    ListBox type = (ListBox)userList.getWidget(row, COLUMN_TYPE);
                    TextBox memberName = (TextBox)userList.getWidget(row, COLUMN_MEMBERNAME);
                    TextBox order = (TextBox)userList.getWidget(row, COLUMN_ORDER);
                    TextBox memberAccount = (TextBox)userList.getWidget(row, COLUMN_MEMBERACCOUNT);

                    String guildNameString = guildName.getText();
                    String realmNameString = realmName.getText();
                    String memberTypeString = type.getItemText(type.getSelectedIndex());
                    String memberNameString = memberName.getText();
                    String orderString = order.getValue();
                    String memberAccountString = memberAccount.getText();

                    errorString = CheckError.checkCreateUser(guildNameString, realmNameString, memberNameString, memberAccountString, orderString);

                    if(errorString.equals("")){
                        targetMember.setGuild(guildNameString);
                        targetMember.setRealm(realmNameString);
                        targetMember.setMembertype(memberTypeString);
                        targetMember.setMemberName(memberNameString);
                        targetMember.setOrder(Long.valueOf(orderString));
                        targetMember.setMemberAccount(memberAccountString);
                    }
                    break;
                }
                if(!errorString.equals("")){
                    break;
                }
            }
            if(!errorString.equals("")){
                break;
            }
        }

        if(errorString.equals("")){
            memberService.setMember(mainUserListMember, new AsyncCallback<Void>(){

                public void onSuccess(Void result){
                    setInfoMessage("Userの更新に成功しました。");
                    clearErrorMessage();
                }

                public void onFailure(Throwable caught){
                    clearInfoMessage();
                    setErrorMessage("Userの更新に失敗しました。");
                }
            });
        }else{
            clearInfoMessage();
            setErrorMessage(errorString);
        }

    }

    private void setUserList(){
        if(userStatus.isAdmin()){
            memberService.getAllMember(new AsyncCallback<ArrayList<Member>>(){

                public void onSuccess(ArrayList<Member> result){
                    userListMember = result;
                    setMainSubCharacter();
                }

                public void onFailure(Throwable caught){
                    clearInfoMessage();
                    setErrorMessage("メンバーの取得に失敗しました。");

                }
            });
        }else{
            memberService.getAllMember(userStatus.getMember(), new AsyncCallback<ArrayList<Member>>(){

                public void onSuccess(ArrayList<Member> result){
                    userListMember = result;
                    setMainSubCharacter();
                }

                public void onFailure(Throwable caught){
                    clearInfoMessage();
                    setErrorMessage("メンバーの取得に失敗しました。");
                }
            });
        }
    }

    protected void setMainSubCharacter(){
        mainUserListMember = new ArrayList<Member>();
        subUserListMember = new ArrayList<Member>();

        for(Member member:userListMember){
            if(member.getMembertype().equals("Officer") || member.getMembertype().equals("Member")){
                mainUserListMember.add(member);
            }else{
                subUserListMember.add(member);
            }
        }

        getuserTypelist();
    }

    private void getuserTypelist(){
        String userType = userTypeList.getItemText(userTypeList.getSelectedIndex());

        if(userType.equals("MainCharacter")){
            setMainCharacterListTable();
        }else{
            setSubCharacterListTable();
        }
    }

    protected void setMainCharacterListTable(){
        boolean isAdmin = userStatus.isAdmin();
        boolean isOfficer = userStatus.isOfficer();

        userList.removeAllRows();
        userList.setText(0, COLUMN_GUILDNAME, "GuildName");
        userList.setText(0, COLUMN_REALM, "Realm");
        userList.setText(0, COLUMN_TYPE, "Type");
        userList.setText(0, COLUMN_MEMBERNAME, "MemberName");

        if(isAdmin || isOfficer){
            userList.setText(0, COLUMN_ORDER, "Order");
            userList.setText(0, COLUMN_MEMBERACCOUNT, "MemberAccount");
        }

        int row = 1;
        for(Member member:mainUserListMember){
            TextBox guildName = new TextBox();
            guildName.setText(member.getGuild());
            userList.setWidget(row, COLUMN_GUILDNAME, guildName);

            TextBox realmName = new TextBox();
            realmName.setText(member.getRealm());
            userList.setWidget(row, COLUMN_REALM, realmName);

            ListBox type = new ListBox();
            type.addItem("Officer");
            type.addItem("Member");
            for(int i = 0;i < type.getItemCount();i++){
                if(member.getMembertype().equals(type.getItemText(i))){
                    type.setSelectedIndex(i);
                    break;
                }
            }
            userList.setWidget(row, COLUMN_TYPE, type);

            TextBox memberName = new TextBox();
            memberName.setText(member.getMemberName());
            userList.setWidget(row, COLUMN_MEMBERNAME, memberName);

            if(isAdmin || isOfficer){
                TextBox order = new TextBox();
                order.setText(String.valueOf(member.getOrder()));
                userList.setWidget(row, COLUMN_ORDER, order);

                TextBox memberAccount = new TextBox();
                memberAccount.setText(member.getMemberAccount());
                userList.setWidget(row, COLUMN_MEMBERACCOUNT, memberAccount);

                Button deleteButton = new Button();
                deleteButton.setText("DELETE");
                setDeleteButton(deleteButton, member);
                userList.setWidget(row, COLUMN_DELETEMEMBER, deleteButton);

                Hidden key = new Hidden();
                key.setValue(member.getKey().toString());
                userList.setWidget(row, COLUMN_HIDDENKEY, key);

                if(!isAdmin && isOfficer){
                    guildName.setReadOnly(true);
                    realmName.setReadOnly(true);
                }

            }else{
                guildName.setReadOnly(true);
                realmName.setReadOnly(true);
                type.setEnabled(false);
                memberName.setReadOnly(true);
            }

            row++;
        }

        if(!isAdmin && !isOfficer){
            setButton.setEnabled(false);
            setButton.setVisible(false);
        }else{
            setButton.setEnabled(true);
            setButton.setVisible(true);
        }

    }

    private void setSubCharacterListTable(){
        boolean isAdmin = userStatus.isAdmin();
        boolean isOfficer = userStatus.isOfficer();

        userList.removeAllRows();
        userList.setText(0, COLUMN_GUILDNAME, "GuildName");
        userList.setText(0, COLUMN_REALM, "Realm");
        userList.setText(0, COLUMN_TYPE, "Type");
        userList.setText(0, COLUMN_MEMBERNAME, "MemberName");

        if(isAdmin || isOfficer){
            userList.setText(0, COLUMN_ORDER, "Order");
            userList.setText(0, COLUMN_MEMBERACCOUNT, "MemberAccount");
        }

        int row = 1;
        for(Member member:subUserListMember){
            TextBox guildName = new TextBox();
            guildName.setText(member.getGuild());
            userList.setWidget(row, COLUMN_GUILDNAME, guildName);

            TextBox realmName = new TextBox();
            realmName.setText(member.getRealm());
            userList.setWidget(row, COLUMN_REALM, realmName);

            Label type = new Label("SubCharacter");
            userList.setWidget(row, COLUMN_TYPE, type);

            TextBox memberName = new TextBox();
            memberName.setText(member.getMemberName());
            userList.setWidget(row, COLUMN_MEMBERNAME, memberName);

            if(isAdmin || isOfficer){
                TextBox order = new TextBox();
                order.setText(String.valueOf(member.getOrder()));
                userList.setWidget(row, COLUMN_ORDER, order);

                TextBox memberAccount = new TextBox();
                memberAccount.setText(member.getMemberAccount());
                userList.setWidget(row, COLUMN_MEMBERACCOUNT, memberAccount);
            }else{
                Hidden order = new Hidden();
                order.setValue(String.valueOf(member.getOrder()));
                userList.setWidget(row, COLUMN_ORDER, order);

                Hidden memberAccount = new Hidden();
                memberAccount.setValue(member.getMemberAccount());
                userList.setWidget(row, COLUMN_MEMBERACCOUNT, memberAccount);
            }

            if(isAdmin || isOfficer || member.getMemberAccount().equals(userStatus.getMember().getMemberAccount())){
                Button deleteButton = new Button();
                deleteButton.setText("DELETE");
                setDeleteButton(deleteButton, member);
                userList.setWidget(row, COLUMN_DELETEMEMBER, deleteButton);
            }else{
                memberName.setReadOnly(true);
            }

            Hidden key = new Hidden();
            key.setValue(member.getKey().toString());
            userList.setWidget(row, COLUMN_HIDDENKEY, key);

            guildName.setReadOnly(true);
            realmName.setReadOnly(true);

            row++;
        }

        if(row != 1){
            setButton.setEnabled(true);
            setButton.setVisible(true);
        }else{
            setButton.setEnabled(false);
            setButton.setVisible(false);
        }

    }

    private void setDeleteButton(Button deleteButton, final Member member){
        deleteButton.addClickHandler(new ClickHandler(){

            public void onClick(ClickEvent event){
                setDelete(member);

            }
        });
    }

    protected void setDelete(Member member){
        new DeleteDialog(member, this).show();
    }

    private class DeleteDialog extends DialogBox{

        public DeleteDialog(final Member member, Userlist userlist){
            setText("Delete Dialog");
            setAnimationEnabled(true);
            setGlassEnabled(true);

            HTMLPanel content = new HTMLPanel("");
            Label deleteLabel = new Label("本当に以下のユーザを削除しますか？");
            Label userLabel = new Label("MemberName:" + member.getMemberName());

            Button okButton = new Button("OK");
            okButton.addClickHandler(new ClickHandler(){
                public void onClick(ClickEvent event){
                    DeleteDialog.this.hide();
                    deleteMemberDialog(member);
                }
            });

            Button cancelButton = new Button("Cancel");
            cancelButton.addClickHandler(new ClickHandler(){
                public void onClick(ClickEvent event){
                    DeleteDialog.this.hide();
                }
            });

            content.add(deleteLabel);
            content.add(userLabel);
            content.add(okButton);
            content.add(cancelButton);
            add(content);

            setPopupPosition(userlist.getOffsetWidth() / 2 - content.getOffsetWidth(), userlist.getOffsetHeight() / 2);

        }

        protected void deleteMemberDialog(Member member){
            deleteMember(member);
        }

    }

    public void deleteMember(final Member member){
        memberService.deleteMemberbyKey(member.getKey().toString(), new AsyncCallback<Void>(){

            public void onSuccess(Void result){
                setInfoMessage("ユーザ\"" + member.getMemberName() + "\"を削除しました。");
                clearErrorMessage();
                setUserList();
            }

            public void onFailure(Throwable caught){
                clearInfoMessage();
                setErrorMessage("ユーザ削除に失敗しました。");
            }
        });
    }
}
